-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Add support for podman quadlet
#26330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: flouthoc The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
[NON-BLOCKING] Packit jobs failed. @containers/packit-build please check. Everyone else, feel free to ignore. |
Why is the quadlet binary bloated by this? the quadlet binary size really needs to be small and avoid any unnecessary imports. |
pkg/systemd/quadlet/unitdirs.go
Outdated
var ( | ||
Errorf func(string, ...interface{}) = logrus.Errorf | ||
Debugf func(string, ...interface{}) = logrus.Debugf | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should not use logrus in quadlet, that is causing the bloat i guess
9cee402
to
c7c1da9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments/questions
cmd/podman/quadlet/remove.go
Outdated
if err != nil { | ||
return err | ||
} | ||
|
||
return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can just return err
if err != nil { | |
return err | |
} | |
return nil | |
return err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
"github.com/containers/podman/v5/pkg/domain/entities" | ||
) | ||
|
||
var errNotImplemented = errors.New("not implemented for the remote Podman client") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it just for this PR, or is it not intended to be implemented for remote?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not as of now, as discussed with @mheon , our priority is to get basic feature in, in future we can explore implementation of API for this. But overall I am still working on this PR by the time I undraft this PR i hope to resolve all your comments, thanks for the feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we'll put it in Q3 prioritization to finish the commands by adding missing things (multi-file, better integration with bootc LBIs, etc)
pkg/domain/infra/abi/quadlet.go
Outdated
installDir := systemdquadlet.UnitDirAdmin | ||
if rootless.IsRootless() { | ||
// Install just for the user in question. | ||
quadletRootlessDirs := systemdquadlet.GetUnitDirs(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure systemdquadlet.GetUnitDirs
acts the way you expect it to. The list of directories is sorted to the order in which the directories were added. So, IIUC the code here it will break some assumptions you have here:
/etc/containers/systemd/users
might be the only one that fits your check. But, this directory is for root to put quadlets for all users. Yes, usually the write check will fail, but nothing guaranties it- Because you don't break from the loop when
foundAdminDir = true
, if there are directories under/etc/containers/systemd/users/$UID
e.g./etc/containers/systemd/users/aaa
and/etc/containers/systemd/users/bbb
, the Quadlets will be installed in/etc/containers/systemd/users/bbb
. It might even go further in if of you have/etc/containers/systemd/users/bbb/z
- Not sure this is all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fixed.
a2b08f8
to
ae01986
Compare
} | ||
return nil | ||
}, | ||
Example: `podman quadlet install /path/to/myquadlet.container |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: what would be the recommend way of installing a kube quadlet? since the YAML would not be copied with this command?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, this is an even bigger questions. Many .container
units come with a configuration file stored locally and mounted into the container. For example, see: https://github.com/containers/appstore/tree/main/quadlet/minio-prometheus. prometheus.yml
must be copied along with prometheus.container
.
Furthermore, if you look at the examples, you can see that in many cases, more than one file is needed (units and others). Can the install
command support installing a directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Furthermore, if you look at the examples, you can see that in many cases, more than one file is needed (units and others). Can the install command support installing a directory?
Yes it supports multiplefile but I think we need to start consuming entire directory as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it supports multiplefile but I think we need to start consuming entire directory as well.
Yes, having to list all the files does not make sense for the user. Plus, as I wrote not all of them will be Quadlet files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we copy resources, we may want to ensure they don't already exists, and have a --force
flag, to allow overwriting existing files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added patch to install from directory in new commit.
If we copy resources, we may want to ensure they don't already exists, and have a --force flag, to allow overwriting existing files
Will add --force
in a follow up PR once this gets merged in order to keep review simpler and not to added too much to matt's original patch.
Problem with directory is, if a directory contains two Or in case of a directory we can just associate all |
Maybe when it's a directory, the identifier shouldn't be at a Quadlet unit level, but an application or deployment (find better name) level. |
I think quadlet list should still show all quadlets independentaly but with another column if they belong to common app and deleting a quadlet from app, should remove entire So it both should remove app
|
e4d2fb5
to
690c3ae
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still need to review the abi
. But, I wanted to put in these comments
cmd/podman/quadlet/list.go
Outdated
var err error | ||
switch { | ||
case cmd.Flag("format").Changed: | ||
rpt, err = rpt.Parse(report.OriginUser, format) | ||
default: | ||
rpt, err = rpt.Parse(report.OriginPodman, format) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var err error | |
switch { | |
case cmd.Flag("format").Changed: | |
rpt, err = rpt.Parse(report.OriginUser, format) | |
default: | |
rpt, err = rpt.Parse(report.OriginPodman, format) | |
} | |
origin := report.OriginPodman | |
if cmd.Flag("format").Changed { | |
origin = report.OriginUser | |
} | |
rpt, err := rpt.Parse(origin, format) |
Remove one or more installed Quadlets from the current user. Following command also takes application name | ||
as input and removes all the Quadlets which belongs to that specific application. | ||
|
||
Note: If quadlet belongs to an application then removing that specific quadlet will remove entire application. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear from reading this and the install page what defines an application
test/system/252-quadlet.bats
Outdated
@@ -1865,4 +1865,164 @@ EOF | |||
|
|||
run_podman rmi -i $image_tag | |||
} | |||
|
|||
@test "quadlet verb - install, list, rm" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I rather they be in a separate file. It's relevant when running the tests locally. I don't see a reason to run the quadlet verb
tests when making changes to quadlet
test/system/252-quadlet.bats
Outdated
|
||
# Test quadlet install | ||
run_podman quadlet install $quadlet_file | ||
assert $status -eq 0 "quadlet install should succeed" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK run_podman
already asserts the value of status
. If first parameter is numeric, it will treat it as the expected value and start the command from the second parameter. Otherwise, it will expect 0.
This is relevant throughout this test
test/system/252-quadlet.bats
Outdated
assert "$output" =~ "Mount=type=bind,source=./test.txt,destination=/test.txt:z" "print should show volume mount configuration" | ||
|
||
# Test quadlet rm | ||
run_podman quadlet rm mount-test.container |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this call expected to also remove the "$install_dir/test.txt"? If yes, it should be verified. If not, aren't we leaving leftovers?
test/system/252-quadlet.bats
Outdated
LogDriver=passthrough | ||
EOF | ||
# Clean all quadlets | ||
run_podman quadlet rm --all -f |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I run this locally, it will remove all my Quadlet files.
test/system/252-quadlet.bats
Outdated
# bats test_tags=distro-integration | ||
@test "quadlet verb - install multiple quadlets from directory and remove by application" { | ||
# Create a temporary directory for multiple quadlet files | ||
local app_name="test-app-$(random_string)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use safe_name
instead of random_string
(throughout)
test/system/252-quadlet.bats
Outdated
# bats test_tags=distro-integration | ||
@test "quadlet verb - install multiple files from directory" { | ||
# Create a directory for multiple quadlet files | ||
local quadlet_dir=$PODMAN_TMPDIR/quadlet-multi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Always use safe_name
to allow parallelism
|
||
## DESCRIPTION | ||
|
||
Install a Quadlet file or an application (which may include multiple Quadlet files) for the current user. You can specify Quadlet files as local files or web URLs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need more details on how applications work here - it's not very clear
|
||
| Filter | Description | | ||
|------------|--------------------------------------------------------------------------------------------------| | ||
| name | Filter by quadlet name. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a TODO somewhere to add an Application filter to this?
pkg/domain/infra/abi/quadlet.go
Outdated
|
||
// AppendStringToFile appends the given text to the specified file. | ||
// If the file does not exist, it will be created with 0644 permissions. | ||
func appendStringToFile(filePath, text string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels like this should be in pkg/util?
pkg/domain/infra/abi/quadlet.go
Outdated
return err | ||
} | ||
|
||
// deleteFilesFromAsset reads .<name>.asset, deletes listed files, then deletes the asset file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this deletes everything it feels like this should be named deleteAsset
instead
| install | [podman-quadlet-install(1)](podman-quadlet-install.1.md) | Install a quadlet file or quadlet application | | ||
| list | [podman-quadlet-list(1)](podman-quadlet-list.1.md) | List installed quadlets | | ||
| print | [podman-quadlet-print(1)](podman-quadlet-print.1.md) | Display the contents of a quadlet | | ||
| rm | [podman-quadlet-rm(1)](podman-quadlet-rm.1.md) | Removes an installed quadlet | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like at some point we need a quadlet inspect
that prints more details. Particularly about the app the quadlet is part of. But that is followon work.
quadlet := quadlets[i] | ||
quadletPath, err := getQuadletByName(quadlet) | ||
if options.All { | ||
quadletPath = quadlet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem right. Why are we even doing getQuadletByName
when options.All
is set?
2e741e1
to
5b328ca
Compare
I haven't found the time for a proper review, I try to get it done next week. |
Your PR is not rebased so I cannot do a proper size comparison. Please remember to rebase all the time when you repush. If I rebase that branch I don't see any new packages being imported other than pkg/logiface which is expected, so we likely should have a closer look what is triggering such a big size increase. |
This adds `podman quadlet list`, `podman quadlet install`, `podman quadlet rm` and `podman quadlet print`. Signed-off-by: Matt Heon <[email protected]> Co-authored-by: flouthoc <[email protected]> Signed-off-by: flouthoc <[email protected]>
Just rebased. |
Does this PR introduce a user-facing change?